package com.ermax.aircond.report.web.bean;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.ermax.aircond.common.domain.UserDetail;
import com.ermax.aircond.common.parameter.Status;
import com.ermax.aircond.maintain.domain.Building;
import com.ermax.aircond.maintain.domain.Floor;
import com.ermax.aircond.maintain.domain.Machine;
import com.ermax.aircond.maintain.domain.Room;
import com.ermax.aircond.maintain.service.MaintainService;
import com.ermax.aircond.report.service.AuditLogService;
import com.ermax.aircond.resource.MessageBundle;
import com.ermax.aircond.util.web.bean.DataTableBean;

@Scope("view")
@Component
public class MainDataAuditLogBean extends DataTableBean implements java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger logger = LoggerFactory.getLogger(MainDataAuditLogBean.class);
	private static final DateFormat DATA_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");

	@Resource(name = "maintainService")
	private MaintainService maintainService;

	@Resource(name = "auditLogService")
	private AuditLogService auditLogService;

	private Date searchFromDate = new Date();
	private Date searchToDate = new Date();
	private long searchAuditUserId = 0L;
	private List<SelectItem> auditUsers = new ArrayList<SelectItem>();

	private long selectedBuildingId;
	private long selectedFloorId;
	private long selectedRoomId;
	private long selectedMachineId;
	private List<SelectItem> buildingOptions = new ArrayList<SelectItem>();
	private List<SelectItem> floorOptions = new ArrayList<SelectItem>();
	private List<SelectItem> roomOptions = new ArrayList<SelectItem>();
	private List<SelectItem> machineOptions = new ArrayList<SelectItem>();
	
	private boolean isShowChat = false;
	

	@PostConstruct
	public void init() {
		try {
			reset();
		} catch (Exception ex) {
			String message = MessageBundle.getInstance().getMessage("error_init_fail", FacesContext.getCurrentInstance().getViewRoot().getLocale());
			FacesMessage facesMessage = new FacesMessage(message);
			FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		}
	}

	private void reset() throws Exception {

		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DAY_OF_YEAR, -7);
		searchFromDate = cal.getTime();
		searchToDate = new Date();
		selectedBuildingId = 0;
		selectedFloorId = 0;
		selectedRoomId = 0;
		selectedMachineId = 0;
		buildingOptions = createBuildingOptions();
		floorOptions = createFloorOptions();
		roomOptions = createRoomOptions();
		machineOptions = createMachineOptions();

		searchAuditUserId = 0;
		auditUsers = createUserDetailOptions();

	}

	public void genExcel(ActionEvent event) throws Exception {

		/*
		if (selectedBuildingId <= 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(MessageBundle.getInstance().getMessage("building_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			sb.append("-");
			sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			FacesMessage facesMessage = new FacesMessage(sb.toString());
			FacesContext.getCurrentInstance().addMessage("search_building_name", facesMessage);
			valid = false;
		}

		if (selectedFloorId <= 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(MessageBundle.getInstance().getMessage("floor_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			sb.append("-");
			sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			FacesMessage facesMessage = new FacesMessage(sb.toString());
			FacesContext.getCurrentInstance().addMessage("search_floor_name", facesMessage);
			valid = false;
		}

		if (selectedRoomId <= 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(MessageBundle.getInstance().getMessage("room_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			sb.append("-");
			sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			FacesMessage facesMessage = new FacesMessage(sb.toString());
			FacesContext.getCurrentInstance().addMessage("search_room_name", facesMessage);
			valid = false;
		}

		if (selectedMachineId <= 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(MessageBundle.getInstance().getMessage("machine_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			sb.append("-");
			sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
			FacesMessage facesMessage = new FacesMessage(sb.toString());
			FacesContext.getCurrentInstance().addMessage("search_machine_name", facesMessage);
			valid = false;
		}
		*/
		
		StringBuilder sbSearchCriteria = new StringBuilder();
		
		List<Machine> machineList = new ArrayList<Machine>();
		if(selectedMachineId > 0){
			Machine machine = maintainService.getMachineById(selectedMachineId);
			machineList.add(machine);
						
			sbSearchCriteria.append(machine.getRoom().getFloor().getBuilding().getBuildingName());
			sbSearchCriteria.append(", ");
			sbSearchCriteria.append(machine.getRoom().getFloor().getFloorName());
			sbSearchCriteria.append(", ");
			sbSearchCriteria.append(machine.getRoom().getRoomName());
			sbSearchCriteria.append(", ");
			sbSearchCriteria.append(machine.getMachineName());				
			
		}else if(selectedRoomId > 0){
			Room room = maintainService.getRoomById(selectedRoomId);
			List<Machine> list = maintainService.getMachines(room);
			machineList.addAll(list);
			
			sbSearchCriteria.append(room.getFloor().getBuilding().getBuildingName());
			sbSearchCriteria.append(", ");
			sbSearchCriteria.append(room.getFloor().getFloorName());
			sbSearchCriteria.append(", ");
			sbSearchCriteria.append(room.getRoomName());			
			
		}else if(selectedFloorId > 0){
			Floor floor = maintainService.getFloorById(selectedFloorId);
			List<Machine> list = maintainService.getMachines(floor);
			machineList.addAll(list);
			
			sbSearchCriteria.append(floor.getBuilding().getBuildingName());
			sbSearchCriteria.append(", ");
			sbSearchCriteria.append(floor.getFloorName());
			
		}else if(selectedBuildingId > 0){
			Building building = maintainService.getBuildingById(selectedBuildingId);
			List<Machine> list = maintainService.getMachines(building);
			machineList.addAll(list);
			
			sbSearchCriteria.append(building.getBuildingName());
			
		}else{
			List<Machine> list = maintainService.getAllMachines();
			machineList.addAll(list);
			
			sbSearchCriteria.append("ALL");
		}
		
		
		
		
		Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
		HSSFWorkbook workbook = auditLogService.getMDataExcelReport(machineList, sbSearchCriteria.toString(), searchFromDate, searchToDate, searchAuditUserId, locale);		

		FacesContext facesContext = FacesContext.getCurrentInstance();
		HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
		response.reset();

		StringBuilder sbHeader = new StringBuilder();
		sbHeader.append("attachment; filename=\"");
		sbHeader.append("LOG_REPORT_");
		sbHeader.append(DATA_FORMAT.format(new Date()));
		sbHeader.append("_");
		sbHeader.append(".xls\"");

		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition", sbHeader.toString());

		ServletOutputStream out = response.getOutputStream();
		workbook.write(out);
		FacesContext.getCurrentInstance().responseComplete();
	}
	
	public void getChart(){
		
	}

	private List<SelectItem> createUserDetailOptions() {
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "ALL"));
		List<UserDetail> userDetails;
		try {
			userDetails = maintainService.getAllUserDetails();
			for (int i = 0; i < userDetails.size(); i++) {
				UserDetail userDetail = userDetails.get(i);
				results.add(new SelectItem(userDetail.getUserId(), userDetail.getUsername()));
			}
		} catch (Exception e) {
			logger.error("MDataAuditLogBean - createUserDetailOptions");
			logger.error(e.getMessage());
		}

		return results;

	}

	public void buildingValueChanged(ValueChangeEvent event) {
		if (null != event.getNewValue()) {
			selectedFloorId = 0;
			selectedRoomId = 0;
			selectedMachineId = 0;
			selectedBuildingId = (Long) event.getNewValue();
			floorOptions = createFloorOptions();
			roomOptions = createRoomOptions();
			machineOptions = createMachineOptions();
		}
	}

	public void floorValueChanged(ValueChangeEvent event) {
		if (null != event.getNewValue()) {
			selectedRoomId = 0;
			selectedMachineId = 0;
			selectedFloorId = (Long) event.getNewValue();
			roomOptions = createRoomOptions();
			machineOptions = createMachineOptions();
		}
	}

	public void roomValueChanged(ValueChangeEvent event) {
		if (null != event.getNewValue()) {
			selectedMachineId = 0;
			selectedRoomId = (Long) event.getNewValue();
			machineOptions = createMachineOptions();
		}
	}

	private List<SelectItem> createBuildingOptions() {
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));
		try {
			List<Building> buildings = maintainService.getAllBuildings(Status.ACTIVE);
			for (Building building : buildings) {
				SelectItem item = new SelectItem(building.getBuildingId(), building.getBuildingName());
				results.add(item);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

		return results;
	}

	private List<SelectItem> createFloorOptions() {
		selectedFloorId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));

		try {
			if (selectedBuildingId > 0) {
				Building selectedBuilding = maintainService.getBuildingById(selectedBuildingId);
				List<Floor> floors = maintainService.getFloors(selectedBuilding, null, Status.ACTIVE);
				for (Floor floor : floors) {
					SelectItem item = new SelectItem(floor.getFloorId(), floor.getFloorName());
					results.add(item);
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return results;
	}

	private List<SelectItem> createRoomOptions() {
		selectedRoomId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));
		try {
			if (selectedFloorId > 0) {
				Floor selectedFloor = maintainService.getFloorById(selectedFloorId);
				List<Room> rooms = maintainService.getRooms(null, selectedFloor, null, Status.ACTIVE);
				for (Room room : rooms) {
					SelectItem item = new SelectItem(room.getRoomId(), room.getRoomName());
					results.add(item);
				}
			}
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
		}
		return results;
	}

	private List<SelectItem> createMachineOptions() {
		selectedMachineId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));
		try {
			if (selectedRoomId > 0) {
				Room selectedRoom = maintainService.getRoomById(selectedRoomId);
				List<Machine> machines = maintainService.getMachines(null, null, selectedRoom, null, Status.ACTIVE);
				for (Machine machine : machines) {
					SelectItem item = new SelectItem(machine.getMachineId(), machine.getMachineName());
					results.add(item);
				}
			}
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
		}
		return results;
	}

	public Date getSearchFromDate() {
		return searchFromDate;
	}

	public void setSearchFromDate(Date searchFromDate) {
		this.searchFromDate = searchFromDate;
	}

	public Date getSearchToDate() {
		return searchToDate;
	}

	public void setSearchToDate(Date searchToDate) {
		this.searchToDate = searchToDate;
	}

	public List<SelectItem> getMachineOptions() {
		return machineOptions;
	}

	public void setMachineOptions(List<SelectItem> machineOptions) {
		this.machineOptions = machineOptions;
	}

	public long getSelectedMachineId() {
		return selectedMachineId;
	}

	public void setSelectedMachineId(long selectedMachineId) {
		this.selectedMachineId = selectedMachineId;
	}

	public long getSearchAuditUserId() {
		return searchAuditUserId;
	}

	public void setSearchAuditUserId(long searchAuditUserId) {
		this.searchAuditUserId = searchAuditUserId;
	}

	public List<SelectItem> getAuditUsers() {
		return auditUsers;
	}

	public void setAuditUsers(List<SelectItem> auditUsers) {
		this.auditUsers = auditUsers;
	}

	public List<SelectItem> getBuildingOptions() {
		return buildingOptions;
	}

	public void setBuildingOptions(List<SelectItem> buildingOptions) {
		this.buildingOptions = buildingOptions;
	}

	public List<SelectItem> getFloorOptions() {
		return floorOptions;
	}

	public void setFloorOptions(List<SelectItem> floorOptions) {
		this.floorOptions = floorOptions;
	}

	public List<SelectItem> getRoomOptions() {
		return roomOptions;
	}

	public void setRoomOptions(List<SelectItem> roomOptions) {
		this.roomOptions = roomOptions;
	}

	public long getSelectedBuildingId() {
		return selectedBuildingId;
	}

	public void setSelectedBuildingId(long selectedBuildingId) {
		this.selectedBuildingId = selectedBuildingId;
	}

	public long getSelectedFloorId() {
		return selectedFloorId;
	}

	public void setSelectedFloorId(long selectedFloorId) {
		this.selectedFloorId = selectedFloorId;
	}

	public long getSelectedRoomId() {
		return selectedRoomId;
	}

	public void setSelectedRoomId(long selectedRoomId) {
		this.selectedRoomId = selectedRoomId;
	}

	public boolean isShowChat() {
		return isShowChat;
	}

	public void setShowChat(boolean isShowChat) {
		this.isShowChat = isShowChat;
	}

}
